package fr.pud.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import fr.pud.client.model.PUDStation;

public class DistanceTable {
    public static final String  IP                 = "172.17.3.101";
    public static final String  SERVER             = "http://"
                                                           + IP
                                                           + ":5000/viaroute&output=json&geomformat=cmp&";
    public static final String  START              = "start=";
    public static final String  DEST               = "dest=";
    public static final String  AMPERSAND          = "&";
    public static final String  COMMA              = ",";
    public static final String  DISTANCE_INDICATOR = "total_distance\":";
    public static final String  TIME_INDICATOR     = "total_time\":";
    public static final int     PARAMETER_QUANTITY = 2;
    public static final boolean TIME               = true;
    public static final boolean DISTANCE           = false;

    public static double computeDistanceBetween2Coordinates(Coordinate a,
            Coordinate b) {
        try {
            URL url;
            url = new URL(SERVER + START + a.getLat() + COMMA + a.getLon()
                    + AMPERSAND + DEST + b.getLat() + COMMA + b.getLon());
            InputStreamReader input = new InputStreamReader(url.openStream());
            BufferedReader buffer = new BufferedReader(input);
            String line = null;
            while ((line = buffer.readLine()) != null) {
                line = line.substring(line.indexOf(TIME_INDICATOR)
                        + TIME_INDICATOR.length());
                line = line.substring(0, line.indexOf(COMMA));
                return Double.parseDouble(line);
            }
            buffer.close();
        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return 0.0;
    }

    public static double computeDistanceBetween2Points(double[] a, double[] b,
            boolean time) {
        try {
            URL url;
            url = new URL(SERVER + START + a[0] + COMMA + a[1] + AMPERSAND
                    + DEST + b[0] + COMMA + b[1]);
            InputStreamReader input = new InputStreamReader(url.openStream());
            BufferedReader buffer = new BufferedReader(input);
            String line = null;
            while ((line = buffer.readLine()) != null) {
                if (time == DISTANCE && line.contains(DISTANCE_INDICATOR)) {
                    line = line.substring(line.indexOf(DISTANCE_INDICATOR)
                            + DISTANCE_INDICATOR.length());
                    line = line.substring(0, line.indexOf(COMMA));
                    return Double.parseDouble(line);
                }
                if (time == TIME && line.contains(TIME_INDICATOR)) {
                    line = line.substring(line.indexOf(TIME_INDICATOR)
                            + TIME_INDICATOR.length());
                    line = line.substring(0, line.indexOf(COMMA));
                    return Double.parseDouble(line);
                }
            }
            buffer.close();
        }
        catch (MalformedURLException e1) {
            e1.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return 0.0;
    }

    public static double[][] computeDistanceMatrix(ArrayList<PUDStation> nodes) {
        int size = nodes.size();
        double[][] matrix = new double[size][size];
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (i != j) {
                    matrix[i][j] = computeDistanceBetween2Coordinates(nodes
                            .get(i).getAddress().getCoordinate(), nodes.get(j)
                            .getAddress().getCoordinate());
                }
                else {
                    matrix[i][j] = 0.0;
                }
            }
        }
        return matrix;
    }
}
